/*
 * wopn2hpp - a small utility to convert a binary file into C header for embedding
 *
 * Copyright (c) 2024 Vitaly Novichkov <admin@wohlnet.ru>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <stdio.h>
#include <string.h>

#define PATH_BUFFER_SIZE        256
#define CHARACTERS_PER_LINE     12

void printUsage(char *arg0)
{
    fprintf(stderr,
            "wopn2hpp\n"
            "Usage: %s input.wopn [output.h]\n", arg0);
}

void printHeader(FILE *out, const char *var_name)
{
    size_t i;
    const char *p;
    char varNameBuf[PATH_BUFFER_SIZE];
    memset(varNameBuf, 0, PATH_BUFFER_SIZE);

    p = strrchr(var_name, '/');
#ifdef _WIN32
    if(p == NULL) p = strrchr(var_name, '\\');
#endif

    if(p) var_name = p + 1;

    memcpy(varNameBuf, var_name, strlen(var_name));

    for(i = 0; i < PATH_BUFFER_SIZE; i++)
    {
        if(varNameBuf[i] == '\0')
            break;
        if(varNameBuf[i] == '.' || varNameBuf[i] == '-')
            varNameBuf[i] = '_';
    }

    fprintf(out,
        "/*===============================================================*\n"
        "   This file is automatically generated by wopn2hpp.sh script\n"
        "   PLEASE DON'T EDIT THIS DIRECTLY. Edit the %s file first,\n"
        "   and then run a wopn2hpp tool to generate this file again\n"
        " *===============================================================*/\n\n"
        "static unsigned char g_%s_bank[] = \n"
        "{\n", var_name, varNameBuf
    );
}

void printFooter(FILE *out)
{
    fprintf(out,
        "\t0x00\n"
        "};\n"
        "\n"
    );
}

int main(int argc, char *argv[])
{
    char outNameBuff[PATH_BUFFER_SIZE];
    unsigned char readBuffer[CHARACTERS_PER_LINE];
    const char *outName = NULL, *inName;
    size_t fileRead = 0, i;
    FILE *inFile, *outFile;

    if(argc == 1)
    {
        printUsage(argv[0]);
        return 2;
    }

    inName = argv[1];

    if(argc >= 3)
        outName = argv[2];
    else
    {
        sprintf(outNameBuff, "%s.h", argv[1]);
        outName = outNameBuff;
    }

    inFile = fopen(inName, "rb");
    if(!inFile)
    {
        fprintf(stderr, "ERROR: Can't open input file %s\n", inName);
        return 1;
    }

    outFile = fopen(outName, "w");
    if(!outFile)
    {
        fprintf(stderr, "ERROR: Can't output input file %s\n", outName);
        return 1;
    }

    printHeader(outFile, inName);

    do
    {
        fileRead = fread(readBuffer, 1, CHARACTERS_PER_LINE, inFile);
        if(fileRead > 0)
        {
            for(i = 0; i < fileRead; i++)
                fprintf(outFile, "%c0x%02x,", (i == 0 ? '\t' : ' '), readBuffer[i]);
            fprintf(outFile, "\n");
        }
    } while(fileRead == CHARACTERS_PER_LINE);

    printFooter(outFile);

    return 0;
}

